package com.funong.matrix.core.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.funong.matrix.core.utils.GlobalConstant.SPLIT_SIGN_DH;
import static com.funong.matrix.core.utils.GlobalConstant.SPLIT_SIGN_FH;


/**
 * 工具类-驼峰和下划线的转换
 */
@Slf4j
public class StringUtil {

    /**
     * 将对象的大写转换为下划线加小写，例如：userName-->user_name
     *
     * @param object
     * @return
     * @throws JsonProcessingException
     */
    public static String toUnderlineJSONString(Object object) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

        objectMapper.setPropertyNamingStrategy(new PropertyNamingStrategy.SnakeCaseStrategy());
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        objectMapper.setDateFormat(dateFormat);


        try {
            return objectMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            log.error("toUnderlineJSONString", e);
        }
        return "";
    }

    /**
     * 将下划线转换为驼峰的形式，例如：user_name-->userName
     *
     * @param json
     * @param clazz
     * @return
     * @throws IOException
     */
    public static <T> T toSnakeObject(String json, Class<T> clazz) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        // mapper的configure方法可以设置多种配置（例如：多字段 少字段的处理）
        //mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        T reqJson = mapper.readValue(json, clazz);
        return reqJson;
    }

    /**
     * 去除特殊符号
     */
    public static String removeEmoji(String text) {
        return text.replaceAll("[\\x{10000}-\\x{10FFFF}]", "");
    }

    /**
     * 下划线命名转驼峰命名
     *
     * @param underscore
     * @return
     */
    public static String underscoreToCamelCase(String underscore) {
        String[] ss = underscore.split("_");
        if (ss.length == 1) {
            return underscore;
        }

        StringBuffer sb = new StringBuffer();
        sb.append(ss[0]);
        for (int i = 1; i < ss.length; i++) {
            sb.append(upperFirstCase(ss[i]));
        }

        return sb.toString();
    }

    /**
     * 驼峰 转下划线
     *
     * @param camelCase
     * @return
     */
    public static String toLine(String camelCase) {
        Pattern humpPattern = Pattern.compile("[A-Z]");
        Matcher matcher = humpPattern.matcher(camelCase);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 首字母 转小写
     *
     * @param str
     * @return
     */
    public static String lowerFirstCase(String str) {
        char[] chars = str.toCharArray();
        chars[0] += 32;
        return String.valueOf(chars);
    }

    /**
     * 首字母 转大写
     *
     * @param str
     * @return
     */
    public static String upperFirstCase(String str) {
        char[] chars = str.toCharArray();
        chars[0] -= 32;
        return String.valueOf(chars);
    }

    public static List<String> splitByNum(String s) {
        List<String> list = new ArrayList<>();
        try {
            String regEx = "[^0-9]";
            Pattern p = Pattern.compile(regEx);
            Matcher m = p.matcher(s);
            String numStr = m.replaceAll("").trim();
            String[] sas = s.split(numStr);
            list.addAll(Arrays.asList(sas));
            list.add(numStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    public static List<String> split(String s, String m) {
        List<String> list = new ArrayList<>();
        try {

            String[] sas = s.split(m);
            for (String sa : sas) {
                if (isNotEmpty(sa)) {
                    list.add(sa);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    public static List<String> split(String s) {
        List<String> list = new ArrayList<>();
        try {

            String m = SPLIT_SIGN_FH;
            if (s.contains(SPLIT_SIGN_DH)) {
                m = SPLIT_SIGN_DH;
            }

            String[] sas = s.split(m);
            for (String sa : sas) {
                if (isNotEmpty(sa)) {
                    list.add(sa);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    public static List<Integer> split1Int(String s) {
        List<Integer> list = new ArrayList<>();
        try {

            String m = SPLIT_SIGN_FH;
            if (s.contains(SPLIT_SIGN_DH)) {
                m = SPLIT_SIGN_DH;
            }

            String[] sas = s.split(m);
            for (String sa : sas) {
                if (isNotEmpty(sa)) {
                    list.add(Integer.valueOf(sa));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    public static List<Integer> split2Int(String s, String m) {
        List<Integer> list = new ArrayList<>();
        try {

            String[] sas = s.split(m);
            for (String sa : sas) {
                if (isNotEmpty(sa)) {
                    list.add(new Integer(sa));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    public static boolean isAllNumber(String s, String m) {
        boolean rtn = true;
        try {

            String[] sas = s.split(m);
            for (String sa : sas) {
                if (isNotEmpty(sa)) {
                    int sn = Integer.valueOf(sa);
                }
            }
        } catch (Exception e) {
            rtn = false;
            e.printStackTrace();
        }
        return rtn;
    }

    public static boolean isEmpty(String s) {
        return null == s || s.isEmpty();
    }

    public static boolean isNotEmpty(String s) {
        return !isEmpty(s);
    }


    /**
     * 判断字符串是否是数字（包含小数）
     *
     * @param s
     * @return
     */
    public static boolean isNumeric(String s) {
        if (isEmpty(s)) {
            return false;
        }
        try {
            new BigDecimal(s);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    public static String formatMoney(Integer money) {
        String moneyCN = "";
        Integer thousand = 10000;
        Integer moneyTM = money / thousand;
        moneyCN = moneyTM + "万";
        return moneyCN;
    }

    public static String formatMonth(Integer month) {
        return month + "个月";
    }

    public static String formatTon(Integer count) {
        return count + "吨";
    }

    public static String filterCustomerEmail(String email) {
        try {
            if (isEmpty(email)) {
                return email;
            }
            Integer start = email.indexOf("@");
            if (null == start || start == 0) {
                return email;
            }
            Integer end = email.substring(start).indexOf(".");
            if (null == end || end < 2) {
                return email;
            }
            String target = email.substring(start, start + end);

            email = email.replace(target, target + "_ldctest");
        } catch (Exception e) {
            e.printStackTrace();
        }

        return email;

    }

    public static String filterCustomerPhone(String phone) {
        try {
            phone = "13800138000";
        } catch (Exception e) {
            e.printStackTrace();
        }

        return phone;

    }

}
